﻿using System;
using System.Printing;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents.Serialization;
using System.Windows.Media;
using System.Windows.Xps;
using System.Windows.Xps.Serialization;

namespace LpbPrj.Client.Tools.Helper
{
    public class PrintHepler
    {
        private static PrintHepler printHepler = null;
        /// <summary>
        /// 打印控件普通A4纸张，缩放之后再打印
        /// </summary>
        /// <param name="visual"></param>
        /// <returns></returns>
        public static bool Print(UserControl visual, Size pageSize, PageOrientation pageOrientation = PageOrientation.Portrait)
        {
            if (visual == null)
            {
                throw new ArgumentNullException("visual");
            }

            if (printHepler == null) printHepler = new PrintHepler();

            try
            {
                XpsDocumentWriter xpsDocumentWriter = printHepler.CreateWriter($"{DateTime.Now.ToShortDateString()}");
                if (printHepler._printQueue == null)
                {
                    throw new ArgumentNullException("PrintQueue");
                }
                if (printHepler._printTicket == null)
                {
                    throw new ArgumentNullException("PrintTicket");
                }

                double width = (double)printHepler._printTicket.PageMediaSize.Width;
                double height = (double)printHepler._printTicket.PageMediaSize.Height;

                //A4纸大小 width=794  height=1123
                double zoom = Math.Min(height / pageSize.Height, width / pageSize.Width);

                // Resize it.
                visual.LayoutTransform = new ScaleTransform(zoom, zoom);

                if (pageOrientation == PageOrientation.Portrait)
                {
                    printHepler._printTicket.PageOrientation = PageOrientation.Portrait;
                    printHepler._printQueue.CurrentJobSettings.CurrentPrintTicket.PageOrientation = PageOrientation.Portrait;

                    // Trigger the sizing of the element.                                    
                    visual.Measure(new Size(width, height));
                    visual.Arrange(new Rect(0, 0, width, height));
                    visual.UpdateLayout();
                }
                if (pageOrientation == PageOrientation.Landscape)
                {
                    printHepler._printTicket.PageOrientation = PageOrientation.Landscape;
                    printHepler._printQueue.CurrentJobSettings.CurrentPrintTicket.PageOrientation = PageOrientation.Landscape;

                    // Trigger the sizing of the element.                                    
                    visual.Measure(new Size(height, width));
                    visual.Arrange(new Rect(0, 0, height, width));
                    visual.UpdateLayout();
                }

                xpsDocumentWriter.Write(visual, printHepler._printTicket);
                return true;
            }
            catch (Exception e)
            {
                //throw e;
                //DataCenter.GetDataCenter().Logger.Error(e.StackTrace);
                //DataCenter.GetDataCenter().Logger.Error(e.Message);
                System.Diagnostics.Debug.WriteLine(e.StackTrace);
                System.Diagnostics.Debug.WriteLine(e.Message);
            }

            return false;
        }
        /// <summary>
        /// 选择缺省打印机
        /// </summary>
        /// <returns></returns>
        public static string PrintSelect()
        {
            if (printHepler == null) printHepler = new PrintHepler();

            printHepler._printTicket = null;
            printHepler._printQueue = null;

            PrintDialog printDialog = new PrintDialog();
            printDialog.PrintTicket.PageOrientation = PageOrientation.Portrait;
            if (printDialog.ShowDialog() == true)
            {
                printHepler._printTicket = printDialog.PrintTicket;
                printHepler._printQueue = printDialog.PrintQueue;

                //设置缺省打印机
                SetDefaultPrinter(printDialog.PrintQueue.FullName);
                return printDialog.PrintQueue.FullName;
            }
            return GetDefaultPrinter();
        }
        /// <summary>
        /// 获取缺省打印机的名称
        /// </summary>
        /// <returns></returns>
        public static string GetDefaultPrinter()
        {
            if (printHepler == null) printHepler = new PrintHepler();

            var printQueue = printHepler.AcquireDefaultPrintQueue();
            return printQueue?.FullName;
        }

        [System.Runtime.InteropServices.DllImport("winspool.drv")]
        private static extern bool SetDefaultPrinter(string Name); //调用win api将指定名称的打印机设置为默认打印机


        private PrintTicket _printTicket = null;
        private PrintQueue _printQueue = null;

        private XpsDocumentWriter CreateWriter(string description)
        {
            PrintQueue printQueue = null;
            PrintTicket printTicket = null;
            XpsDocumentWriter xpsDocumentWriter = null;
            PickCorrectPrintingEnvironment(ref printQueue, ref printTicket);

            if (printQueue != null)
            {
                printQueue.CurrentJobSettings.Description = description;
            }

            xpsDocumentWriter = PrintQueue.CreateXpsDocumentWriter(printQueue);
            PrintDlgPrintTicketEventHandler @object = new PrintDlgPrintTicketEventHandler(printTicket);
            xpsDocumentWriter.WritingPrintTicketRequired += @object.SetPrintTicket;
            return xpsDocumentWriter;
        }

        private void PickCorrectPrintingEnvironment(ref PrintQueue printQueue, ref PrintTicket printTicket)
        {
            if (_printQueue == null)
            {
                _printQueue = AcquireDefaultPrintQueue();
            }

            if (_printTicket == null)
            {
                _printTicket = AcquireDefaultPrintTicket(_printQueue);
            }

            printQueue = _printQueue;
            printTicket = _printTicket;
        }

        private PrintQueue AcquireDefaultPrintQueue()
        {
            try
            {
                LocalPrintServer localPrintServer = new LocalPrintServer();
                return localPrintServer.DefaultPrintQueue;
            }
            catch (PrintSystemException)
            {
                return null;
            }
        }

        private PrintTicket AcquireDefaultPrintTicket(PrintQueue printQueue)
        {
            PrintTicket printTicket = null;
            try
            {
                if (printQueue != null)
                {
                    printTicket = printQueue.UserPrintTicket;
                    if (printTicket == null)
                    {
                        printTicket = printQueue.DefaultPrintTicket;
                    }
                }
            }
            catch (PrintSystemException)
            {
                printTicket = null;
            }

            if (printTicket == null)
            {
                printTicket = new PrintTicket();
            }

            return printTicket;
        }

        internal class PrintDlgPrintTicketEventHandler
        {
            private PrintTicket _printTicket;

            public PrintDlgPrintTicketEventHandler(PrintTicket printTicket)
            {
                _printTicket = printTicket;
            }

            public void SetPrintTicket(object sender, WritingPrintTicketRequiredEventArgs args)
            {
                if (args.CurrentPrintTicketLevel == PrintTicketLevel.FixedDocumentSequencePrintTicket)
                {
                    args.CurrentPrintTicket = _printTicket;
                }
            }
        }

    }
}
